package com.devshephard.rpcframework.rpc.service.rpcservice.impl.original;


import com.devshephard.rpcframework.rpc.component.tcp.netty.client.handler.RpcResponseMessageHandler;
import com.devshephard.rpcframework.rpc.component.tcp.netty.message.RpcRequestMessage;
import com.devshephard.rpcframework.rpc.component.tcp.netty.protocol.SequenceIdGenerator;
import com.devshephard.rpcframework.rpc.factory.channel.SingletonClientChannelFactory;
import io.netty.util.concurrent.DefaultPromise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Proxy;


public class RpcServiceTcpImplOriginal<T> implements FactoryBean<T>, InitializingBean, ApplicationContextAware {

    private Logger logger =
            LoggerFactory.getLogger(RpcServiceTcpImplOriginal.class);

    private Class<T> target;

    public RpcServiceTcpImplOriginal(Class<T> target) {
        this.target = target;
    }

    @Override
    public T getObject() {

        ClassLoader loader = target.getClassLoader();
        Class<?>[] interfaces = new Class[]{target};
        //                                                            sayHello  "张三"
        Object obj = Proxy.newProxyInstance(loader, interfaces, (proxy, method, args) -> {
            // 1. 将方法调用转换为 消息对象
            int sequenceId = SequenceIdGenerator.nextId();
            RpcRequestMessage msg = new RpcRequestMessage(
                    sequenceId,
                    target.getName(),
                    method.getName(),
                    method.getReturnType(),
                    method.getParameterTypes(),
                    args
            );

            // 2. 准备一个空 Promise 对象，来接收结果             指定 promise 对象异步接收结果线程,即当promise创建监听器时,返回结果由getChannel().eventLoop()中的新线程执行（即62-66行代码）
            DefaultPromise<Object> promise = new DefaultPromise<>(SingletonClientChannelFactory.getChannel().eventLoop());
            RpcResponseMessageHandler.PROMISES.put(sequenceId, promise);

            // 3. 将消息对象发送出去
            SingletonClientChannelFactory.getChannel().writeAndFlush(msg);

            /*  promise.addListener(future -> {
                // 线程
                // 这里的 future 就是上面的 promise
                System.out.println(Thread.currentThread().getName() + " " + future.getNow());
            });*/

            // 4. 等待 promise 结果

            promise.await();
            if(promise.isSuccess()) {
                // 调用正常
                return promise.getNow();
            } else {
                // 调用失败
                throw new RuntimeException(promise.cause());
            }
        });

        return (T) obj;

    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }


    @Override
    public void afterPropertiesSet() throws Exception {

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

    }
}
